﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ViewFaceCore.Model;
using ViewFaceCore.Core;
using ViewFaceCore;
using SkiaSharp;
using OcrWinForm.Extensions;

namespace OcrWinForm.Controls
{
    public partial class FaceControl : UserControl
    {
        public FaceControl()
        {
            InitializeComponent();
        }

        //导入图片
        private void button1_Click(object sender, EventArgs e)
        {
            //打开文件选择器
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "Image Files|*.jpg;*.jpeg;*.png;";
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    Image image = Image.FromFile(openFileDialog.FileName); //获取图片
                    pictureBox1.Image = image; //图片容器 赋值
                    pictureBox1.ImageLocation = openFileDialog.FileName;  //图片容器 赋值
                }
            }
        }

        //识别人像
        private async void button2_ClickAsync(object sender, EventArgs e)
        {
            //使用SKBitmap.Decod 方法从图片路径中加载图像
            // 这里使用的是skiaSharp库来处理图片
            var bitmap = SKBitmap.Decode(pictureBox1.ImageLocation);

            //从PicTureBox 控件中加载图片并转换为Bitmap对象
            Bitmap bitmap2 = new(pictureBox1.Image);

            //初始化一个faceDetector对象
            FaceDetector faceDetector = new FaceDetector();

            //将skiaSharp 的bitmap 对象转为FaceImage对象
            FaceImage faceImage = bitmap.ToFaceImage();

            //异步检测图像中的面部
            var faces = await faceDetector.DetectAsync(faceImage);

            //在bitmap2 图像上绘制矩形框以标记检测到的面部
            using (Graphics g = Graphics.FromImage(bitmap2))
            {
                foreach (var face in faces)
                {
                    //绘制红色矩形框标记面部区域
                    g.DrawRectangle(new Pen(Color.Red, 10), new Rectangle()
                    {
                        X = face.Location.X,
                        Y = face.Location.Y,
                        Height = face.Location.Height,
                        Width = face.Location.Width
                    });
                }
            }

            //将处理后的图像重新赋值给 pictrueBox 控件
            pictureBox1.Image = bitmap2;

            //释放bitmap对象
            bitmap.Dispose();

            //显示包含检测到的面部数量的消息框
            MessageBox.Show($"找到了{faces.Length}张人脸");

        }
        //性别检查
        private void button3_Click(object sender, EventArgs e)
        {
            // 从 PictureBox 控件的图像路径加载图像，并将其转换为 FaceImage 对象
            FaceImage img = SKBitmap.Decode(pictureBox1.ImageLocation).ToFaceImage();
            // 初始化一个 FaceDetector 对象，用于检测人脸
            FaceDetector faceDetector = new FaceDetector();
            // 检测图像中的人脸，返回的结果取第一个人脸信息
            var info = faceDetector.Detect(img).First();
            // 初始化一个 genderPredictor 对象，用于预测性别
            GenderPredictor genderPredictor = new GenderPredictor();
            // 初始化一个 FaceLandmarker 对象，用于标记人脸的特征点
            FaceLandmarker faceMark = new FaceLandmarker();
            // 获取人脸的特征点
            var points = faceMark.Mark(img, info);
            // 使用 GenderPredictor 对象预测性别
            Gender gender = genderPredictor.PredictGender(img, points);
            // 显示预测的年龄
            MessageBox.Show(gender.ToString());
        }
        //年龄检测
        private void button4_Click(object sender, EventArgs e)
        {
            // 从 PictureBox 控件的图像路径加载图像，并将其转换为 FaceImage 对象
            FaceImage img = SKBitmap.Decode(pictureBox1.ImageLocation).ToFaceImage();
            // 初始化一个 FaceDetector 对象，用于检测人脸
            FaceDetector faceDetector = new FaceDetector();
            // 检测图像中的人脸，返回的结果取第一个人脸信息
            var info = faceDetector.Detect(img).First();
            // 初始化一个 AgePredictor 对象，用于预测年龄
            AgePredictor agePredictor = new AgePredictor();
            // 初始化一个 FaceLandmarker 对象，用于标记人脸的特征点
            FaceLandmarker faceMark = new FaceLandmarker();
            // 获取人脸的特征点
            var points = faceMark.Mark(img, info);
            // 使用 AgePredictor 对象预测年龄
            int age = agePredictor.PredictAge(img, points);
            // 显示预测的年龄
            MessageBox.Show(age.ToString());
        }

        private void button5_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "Image Files|*.jpg;*.jpeg;*.png;";
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    pictureBox2.Image = Image.FromFile(openFileDialog.FileName);
                    pictureBox2.ImageLocation = openFileDialog.FileName;
                }
            }
        }

        //对比图像
        private void button6_Click(object sender, EventArgs e)
        {
            float[] f1 = ExtractFeature(pictureBox1.ImageLocation);
            float[] f2 = ExtractFeature(pictureBox2.ImageLocation);

            FaceRecognizer faceRecognizer = new();

            //对比特征
            bool isSelf = faceRecognizer.IsSelf(f1, f2);
            //计算相似度
            float similarity = faceRecognizer.Compare(f1, f2);

            string msg = "识别到的人脸是否为同一个人：" + isSelf + ",相似度：" + similarity;
            MessageBox.Show(msg);
        }

        public float[]? ExtractFeature(string imagePath)
        {
            using var faceImage = SKBitmap.Decode(imagePath).ToFaceImage();

            //检测人脸信息
            FaceDetector faceDetector = new();
            FaceInfo[] fi = faceDetector.Detect(faceImage);
            float[]? data0 = null;
            if (fi.Length > 0)
            {
                //标记人脸位置
                FaceLandmarker faceMark = new();
                FaceMarkPoint[] points = faceMark.Mark(faceImage, fi[0]);

                FaceRecognizer faceRecognizer = new();
                data0 = faceRecognizer.Extract(faceImage, points);
            }
            return data0;
        }
    }
}
